home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
mg2a_src.zip
/
TERMLIB
/
TGOTO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-16
|
5KB
|
191 lines
/************************************************************************
* *
* Copyright (c) 1982, Fred Fish *
* All Rights Reserved *
* *
* This software and/or documentation is released for public *
* distribution for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. *
* *
************************************************************************
*/
/*
* Modified:
* 1 May 86 ...!ihnp4!ut-sally!ut-ngp!mic
* Now forces a '\0' at end of tgoto string. Tgoto wasn't,
* and this screwed up VT100-style (i.e. variable) cursor
* addressing.
*
* 22 Jan 89 blarson@skat.usc.edu
* Fix %. so it won't generate '\0'. This requires UP
* and BC externals. Avoid troucing memory if bad format
* string given. Make smaller and faster. Some comments
* on the obvious eliminated to make code easier to read.
*/
/*
* LIBRARY FUNCTION
*
* tgoto expand cursor addressing string from cm capability
*
* KEY WORDS
*
* termcap
*
* SYNOPSIS
*
* extern char *UP;
* extern char *BC;
*
* char *tgoto(cm,destcol,destline)
* char *cm;
* int destcol;
* int destline;
*
* DESCRIPTION
*
* Returns cursor addressing string, decoded from the cm
* capability string, to move cursor to column destcol on
* line destline.
*
* The following sequences uses one input argument, either
* line or column, and place the appropriate substitution
* in the output string:
*
* %d substitute decimal value (in ASCII)
* %2 like %d but forces field width to 2
* %3 like %d but forces field width to 3
* %. like %c
* %+x like %c but adds ASCII value of x
*
* The following sequences cause processing modifications
* but do not "use up" one of the arguments. If they
* act on an argument they act on the next one to
* be converted.
*
* %>xy if next value to be converted is
* greater than value of ASCII char x
* then add value of ASCII char y.
* %r reverse substitution of line
* and column (line is substituted
* first by default).
* %i causes input values destcol and
* destline to be incremented.
* %% gives single % character in output.
*
* BUGS
*
* Does not implement some of the more arcane sequences for
* radically weird terminals (specifically %n, %B, & %D).
* If you have one of these you deserve whatever happens.
*
*/
#include <stdio.h>
extern char *UP; /* sequence to goto previous line */
extern char *BC; /* sequence to goto previous char */
char *tgoto(cm,destcol,destline)
char *cm;
int destcol;
int destline;
{
register char *in; /* Internal copy of input string pointer */
register char *out; /* Pointer to output array */
register int pcount; /* Count of args processed */
int args[2]; /* args to convert */
static char output[64]; /* Converted string */
int repos; /* flags that UP and BC are needed */
/* 1 for UP, 2 for BC, 3 for both */
if (cm == NULL) return "OOPS";
in = cm;
out = output;
args[0] = destline;
args[1] = destcol;
pcount = 0;
repos = 0;
while (*in != '\0') {
if (*in != '%') {
*out++ = *in++;
} else {
in++;
switch(*in++) {
case 'd':
sprintf(out,"%d",args[pcount]);
out = &output[strlen(output)];
pcount ^= 1;
break;
case '2':
sprintf(out,"%02d",args[pcount]);
out = &output[strlen(output)];
pcount ^= 1;
break;
case '3':
sprintf(out,"%03d",args[pcount]);
out = &output[strlen(output)];
pcount ^= 1;
break;
case '.':
if((*out++ = args[pcount]) == '\0') {
out[-1]++;
repos |= pcount+1;
}
pcount ^= 1;
break;
case '+':
if((*out++ = args[pcount] + *in++) == '\0') {
out[-1]++;
repos |= pcount+1;
}
pcount ^= 1;
break;
case '>':
if (args[pcount] > *in++) {
args[pcount] += *in++;
} else {
in++;
}
break;
case 'r':
pcount ^= 1;
break;
case 'i':
args[0]++;
args[1]++;
break;
case '%':
*out++ = '%';
break;
}
}
}
if(repos) {
if(repos & 1) {
if(UP != NULL) {
in = UP;
while(*in) *out++ = *in++;
} /* else the output is screwed up */
}
if(repos & 2) {
if(BC != NULL && *BC != '\0') {
in = BC;
while(*in) *out++ = *in++;
} else {
*out++ = '\b';
}
}
}
*out = '\0';
return output;
}